/*
自动化编译
tsc index 将ts文件转化为js文件，让浏览器识别
*/
//#region 限制变量类型
var msg:string;
var id:number;
var is:boolean;

msg = "hello";
id = 10;
is = true;
// console.log(msg,id,is);
//#endregion

//#region 限制返回值类型
function addMsg(x:number,y:number):string{
    return x + y +"√";
}
var result = addMsg(1,2);
// console.log(result);

//留给底层自动装箱使用
var msgs: String  
//#endregion

//#region any/unknown
//定义未使用undefined
let any1:any = "hello world";
let un:unknown;
let msg1:string;
msg1 = any1;
var upper = any1.toUpperCase();
any1.money; //TypeError:Cannot create property 'money' on string 'hello world'
// console.log(upper);
// console.log(msg1);

//使用安全的unknown需要进行类型断言
msg1 = un as string;
msg1 = <string>un;

//第一种断言方式if
if(typeof un === "string"){
    //使用unknown进行函数返回值断言
    (un as string).toUpperCase();
}
//#endregion

//#region 函数never类型

/*
1、函数没有返回值，就返回undefined
2、函数never类型用于函数的递归调用，或者是非正常结束
3、never变量类型是由编译器推断
*/
function exception():never{ 
    throw new Error("请联系管理员处理!!!");
}

var ever:string;
var ever1 = "hello world";

if(typeof ever1 === "string"){
    // console.log(ever1.toUpperCase());
}else{
    console.log(ever1);
}
//#endregion

//#region undefined和void返回值区别
function undefined1():undefined{
    return undefined;
}

var undefinedVar = undefined1();
// if(undefinedVar){
// }

function void1():void{
    // return undefined;
    // return;
    // console.log("void1");
}

var voidVar = void1();
// 区别函数返回值不能被使用
// if(voidVar){
// }
//#endregion

//#region （动态属性对象）定义Object的索引签名，允许有任意数据的属性，键可变（string）
var obj1:object;
// obj1 = 1, object不包含基本数据类型
var obj2:Object;
//Object只包含可以调用Object方法的任意类型
// obj2 = null
// obj2 = undefined
var obj3:{
    [key:string]:any;
}
obj3 = {
    name:"zhangsan",
    age:18,
    sex:'male'
}
// console.log(obj3);
//#endregion

//#region 函数的声明;=>申明函数
var fun:(a:number,b:number) => number;

fun = function(x,y){
    return x+y;
}

//lambda表达式;=>箭头函数
fun = (x,y) =>{
    return x+y;
}
//#endregion

//#region 数组定义
var arr1: string[];
var arr2: Array<number>;

arr1 = ["hello","world"];
arr2 = [1,2,3];
// console.log(arr1);
//#endregion console.log(arr2);

//#region 元组定义
var arr3:[string,number];
var arr4:[number,...string[]];
var arr5:[string,boolean];

arr3 = ["hello",1];
arr4 = [1,"hello","word","!"];
arr5 = ["word",false];

// console.log(arr3,arr4,arr5);
//#endregion

//#region 枚举定义
//常数枚举使用字符串访问，少些代码
const enum Days{
    Sun,
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat
}
// console.log(Days.Sun);
//#endregion

//#region 联合/交叉类型/lambda表达式一句话时可不使用{}。type类型：number,number怎么用==type怎么用
type Sex = "男" | "女" | "未知";
type Status = number | string;

var printTest = function(val: Sex):void{
// console.log(val)
}
printTest("未知");

function StatusFun(val:Status):void{
    // console.log(val);
}
StatusFun(1);

type ability = {
    code:string,
    study:string
}

type money = {
    buy:number,
    time:number
}

type lxy = ability & money;
const goodAndBad:lxy = {
    code:"初级",
    study:"初级",
    buy:30,
    time:70
}
// console.log(goodAndBad);

// type_fun类型的() =>返回void
type type_fun = () => void;
const typeFun1: type_fun = function(){
    return 68;
}

var arrs:Array<number> = [1,2,3];
var arrs1:Array<number> = [0];
//forEach是void，使用push会得到int返回值，目前把push的返回值作为forEach的返回值！
arrs.forEach((x)=> arrs1.push(x));
//#endregion



